package ld.oauth.blog.service.question.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ld.oauth.blog.mapper.question.QuestionMapper;
import ld.oauth.blog.model.bo.QuestionBo;
import ld.oauth.blog.model.bo.ReplyBo;
import ld.oauth.blog.model.po.question.Question;
import ld.oauth.blog.model.po.question.QuestionCategory;
import ld.oauth.blog.model.po.question.QuestionLabel;
import ld.oauth.blog.model.po.question.Reply;
import ld.oauth.blog.model.po.user.SysUser;
import ld.oauth.blog.model.qo.QuestionQo;
import ld.oauth.blog.model.vo.LabelVo;
import ld.oauth.blog.model.vo.QuestionDetail;
import ld.oauth.blog.model.vo.ReplyVo;
import ld.oauth.blog.service.question.QuestionCategoryService;
import ld.oauth.blog.service.question.QuestionLabelService;
import ld.oauth.blog.service.question.QuestionService;
import ld.oauth.blog.service.question.ReplyService;
import ld.oauth.blog.service.user.SysUserService;
import ld.oauth.blog.utils.PageResult;
import ld.oauth.blog.utils.PageUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.SetUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author ld
 * @since 2022-09-25
 */
@Service
public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> implements QuestionService {

    @Autowired
    private QuestionCategoryService questionCategoryService;

    @Autowired
    private QuestionLabelService questionLabelService;

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private ReplyService replyService;

    /**
     * 新增或编辑问题
     * @param questionBo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer insertOrUpdate(QuestionBo questionBo) {
        Question question = new Question();
        BeanUtils.copyProperties(questionBo,question);
        this.saveOrUpdate(question);
        //绑定的文章分类和标签
        List<List<Integer>> list = questionBo.getLabelIds();
        Set<Integer> categoryList = SetUtils.newIdentityHashSet();
        Set<Integer> labeIdList = SetUtils.newIdentityHashSet();
        if (!CollectionUtils.isEmpty(list)) {
            list.stream().forEach(listChild -> {
                categoryList.add(listChild.get(0));//问题分类id
                labeIdList.add(listChild.get(1));//标签id
            });
            //问题绑定分类和标签
            questionBindCategoryAndLabel(question, categoryList, labeIdList);
        }
        return question.getId();
    }

    /**
     * 问题绑定分类和标签
     * @param question
     * @param categoryList
     * @param labeIdList
     */
    public void questionBindCategoryAndLabel(Question question, Set<Integer> categoryList, Set<Integer> labeIdList) {
        //先删除 再绑定
        questionCategoryService.removeCategoryIdsByQuestionId(question.getId());
        List<QuestionCategory> questionCategoryList = new ArrayList<>();
        categoryList.stream().forEach(categoryId -> {
            QuestionCategory questionCategory = new QuestionCategory();
            questionCategory.setQuestionId(question.getId());
            questionCategory.setCategoryId(categoryId);
            questionCategoryList.add(questionCategory);
        });
        questionCategoryService.saveBatch(questionCategoryList);
        //先删除 再绑定
        questionCategoryService.removeLabelsIdsByQuestionId(question.getId());
        List<QuestionLabel> questionLabelList = new ArrayList<>();
        labeIdList.stream().forEach(labelId -> {
            QuestionLabel questionLabel = new QuestionLabel();
            questionLabel.setQuestionId(question.getId());
            questionLabel.setLabelId(labelId);
            questionLabelList.add(questionLabel);
        });
        questionLabelService.saveBatch(questionLabelList);
    }

    /**
     * 根据问题id查询文章详情
     * @param id
     * @return
     */
    @Override
    public QuestionDetail questionDetailById(Integer id) {
        Question question = this.getBaseMapper().selectById(id);
        QuestionDetail questionDetail = new QuestionDetail();
        BeanUtils.copyProperties(question, questionDetail);
        List<LabelVo> labelVoList = this.getBaseMapper().selectLabelVoListByQuestionId(id);
        List<List<Integer>> labelIds = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(labelVoList)) {
            labelVoList.stream().forEach(labelVo -> {
                List<Integer> list = new ArrayList<>();
                list.add(labelVo.getCategoryId());
                list.add(labelVo.getId());
                labelIds.add(list);
            });
            questionDetail.setLabelIds(labelIds);
        }
        //封装人的信息
        SysUser sysUser = sysUserService.findById(Long.valueOf(question.getCreator()));
        if(!Objects.isNull(sysUser)){
            questionDetail.setUserImage(sysUser.getImageUrl());
            questionDetail.setNickName(sysUser.getNickName());
        }
        return questionDetail;
    }

    /**
     * 分页条件查询最热问题
     * @param questionQo
     * @return
     */
    @Override
    public PageResult<QuestionDetail> hot(QuestionQo questionQo) {
        IPage<QuestionDetail> iPage = PageUtil.createIPage(questionQo);
        PageResult<QuestionDetail> hot = this.getBaseMapper().hot(questionQo, iPage);
        return hot;
    }

    /**
     * 分页条件查询最新问题
     * @param questionQo
     * @return
     */
    @Override
    public PageResult<QuestionDetail> veryNew(QuestionQo questionQo) {
        IPage<QuestionDetail> iPage = PageUtil.createIPage(questionQo);
        PageResult<QuestionDetail> veryNew = this.getBaseMapper().veryNew(questionQo, iPage);
        return veryNew;
    }

    /**
     * 分页条件查询等待回答问题
     * @param questionQo
     * @return
     */
    @Override
    public PageResult<QuestionDetail> wait(QuestionQo questionQo) {
        IPage<QuestionDetail> iPage = PageUtil.createIPage(questionQo);
        PageResult<QuestionDetail> wait = this.getBaseMapper().wait(questionQo, iPage);
        return wait;
    }

    /**
     * 更新问题浏览数
     * @param id
     */
    @Override
    public void updateArticleViewCountById(Integer id) {
        Question question = this.baseMapper.selectById(id);
        question.setViewCount((question.getViewCount() + 1));
        this.baseMapper.updateById(question);
    }


    /**
     * 更新问题点赞数
     * @param questionId
     * @param count
     */
    @Override
    public void updateArticleThumbById(Integer questionId, Integer count) {
        Question question = this.baseMapper.selectById(questionId);
        question.setThumhup((question.getThumhup() + count));
        this.baseMapper.updateById(question);
    }

    /**
     * 新增或修改问题的回答
     * @param replyBo
     * @return
     */
    @Override
    public boolean insertOrUpdateQuestionReplay(ReplyBo replyBo) {
        Reply reply = new Reply();
        BeanUtils.copyProperties(replyBo,reply);
        return replyService.saveOrUpdate(reply);
    }

    /**
     * 根据问题id获取问题的所有回答
     * @param questionId
     * @return
     */
    @Override
    public List<ReplyVo> getQuestionReplayById(Integer questionId) {
        List<ReplyVo> replyVoList = this.baseMapper.getQuestionReplayById(questionId,-1);
        //递归查询是否有子评论
        handleReplyChildList(questionId,replyVoList);
        return replyVoList;
    }

    /**
     * 递归查询是否有子评论
     * @param questionId
     * @param replyVoList
     */
    public void handleReplyChildList(Integer questionId,List<ReplyVo> replyVoList){
        if(CollectionUtils.isNotEmpty(replyVoList)){
            replyVoList.stream().forEach(replyVo->{
                List<ReplyVo> childList = this.baseMapper.getQuestionReplayById(questionId, replyVo.getId());
                replyVo.setChildren(childList);
                handleReplyChildList(questionId,childList);
            });
        }else {
            return;
        }
    }

    /**
     * 根据标签id分页查询问题列表
     * @param questionQo
     * @return
     */
    @Override
    public PageResult<QuestionDetail> queryQuestionByLabelId(QuestionQo questionQo) {
        IPage<QuestionDetail> iPage = PageUtil.createIPage(questionQo);
        PageResult<QuestionDetail> questionDetailPageResult = this.baseMapper.queryQuestionByLabelId(questionQo, iPage);
        return questionDetailPageResult;
    }



}
